package com.sl.core.engine.log.store.file;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.*;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.PageResult;
import com.sl.core.engine.log.store.AbstractDbLogStore;
import com.sl.core.engine.log.store.IProcessLogStore;
import com.sl.core.engine.log.store.domain.bo.ProcessLogListByConditionBO;
import com.sl.core.engine.log.store.domain.dto.LogDetailDTO;
import com.sl.core.engine.log.store.domain.dto.MainLogDTO;
import com.sl.core.engine.log.store.domain.entity.LogDetailDO;
import com.sl.core.engine.log.store.domain.entity.MainLogDO;
import com.sl.core.engine.rowset.ProcessFileRowSet;
import com.sl.core.engine.utils.ZipUtil;
import lombok.SneakyThrows;
import org.anyline.data.param.ConfigStore;
import org.anyline.data.param.init.DefaultConfigStore;
import org.anyline.entity.DataSet;
import org.anyline.entity.EntitySet;
import org.anyline.service.AnylineService;
import org.apache.commons.compress.utils.Lists;

import java.io.File;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class LocalFileProcessLogStore extends AbstractDbLogStore implements IProcessLogStore {

    public LocalFileProcessLogStore() {
        super.initDb();
    }

    @Override
    protected String getJdbcUserName() {
        return "root";
    }

    @Override
    protected String getJdbcPassword() {
        return "123456";
    }

    @Override
    protected String getJdbcUrl() {
        File projectFile = createRootFile();
        return initFiles(projectFile.getPath() + File.separator + "log.db");
    }

    protected String getJdbcUrl(Date date) {
        File projectFile = createRootFile(date);
        return initFiles(projectFile.getPath() + File.separator + "log.db");
    }

    @Override
    protected String getJdbcDriver() {
        return "org.sqlite.JDBC";
    }

    @SneakyThrows
    private String initFiles(String file) {
        return "jdbc:sqlite:" + file;
    }

    public static File createRootFile() {
        return createRootFile(DateUtil.date());
    }

    @SneakyThrows
    public static File createRootFile(Date date) {
        File baseRootFile = getBaseRootFile();
        String format = DateUtil.format(date, DatePattern.PURE_DATE_PATTERN);

        File file = FileUtil.file(baseRootFile, format);
        if (!file.exists()) {
            synchronized (ProcessFileRowSet.class) {
                if (!file.exists()) {
                    file.mkdir();
                }
            }
        }
        return file;
    }


    public static File getBaseRootFile() {
        String property = System.getProperty("user.home");
        File file = FileUtil.file(property + File.separator + "square_lake");
        if (!file.exists()) {
            synchronized (ProcessFileRowSet.class) {
                if (!file.exists()) {
                    file.mkdir();
                }
            }
        }
        file = FileUtil.file(property + File.separator + "square_lake" + File.separator + "logs");
        if (!file.exists()) {
            synchronized (ProcessFileRowSet.class) {
                if (!file.exists()) {
                    file.mkdir();
                }
            }
        }
        return file;
    }


    @Override
    public List<MainLogDTO> listByCondition(ProcessLogListByConditionBO processLogListByConditionBO) {


        Date startDate = processLogListByConditionBO.getStartDate();
        Date endDate = processLogListByConditionBO.getEndDate();

        String processId = processLogListByConditionBO.getProcessId();
        String keywords = processLogListByConditionBO.getKeywords();
        String tid = processLogListByConditionBO.getTid();
        String instanceId = processLogListByConditionBO.getInstanceId();

        Integer size = processLogListByConditionBO.getSize();
        Integer current = processLogListByConditionBO.getCurrent();


        //必须带入时间查询
        if (!ObjectUtil.isAllNotEmpty(startDate, endDate)) {
            return Collections.emptyList();
        }

        DateRange range = DateUtil.range(startDate, endDate, DateField.DAY_OF_YEAR);


        List<MainLogDO> list = Lists.newArrayList();
        PageResult pageResult = new PageResult(current, size);
        Integer count = 0;
        for (DateTime dateTime : range) {
            AnylineService anylineService = initDb(getJdbcUrl(dateTime));

            ConfigStore configStore = new DefaultConfigStore();
            if (StrUtil.isNotBlank(tid)) {
                configStore.and("tid", tid);
            }
            if (StrUtil.isNotBlank(instanceId)) {
                configStore.and("instanceId", instanceId);
            }
            if (StrUtil.isNotBlank(processId)) {
                configStore.and("processId", processId);
            }
            if (StrUtil.isNotBlank(keywords)) {
                configStore.like("feature", keywords);
            }

            configStore.columns(" distinct tid ");

            Long co = 0L;
            try {
                co = anylineService.count(getTableName(LogDetailDO.class), configStore);
            } catch (Exception e) {
            }
            count += co.intValue();

            configStore.page(current, size);
            //开始查询
            DataSet querys = null;
            try {
                querys = anylineService.querys(getTableName(LogDetailDO.class), configStore);
            } catch (Exception e) {

            }
            if (CollUtil.isEmpty(querys)) {
                continue;
            }
            List<String> tidList = querys.stream().map(v -> v.getString("tid")).distinct().toList();

            configStore = new DefaultConfigStore();
            configStore.in("tid", tidList);

//            configStore.page(current, size);
            //查询主表
            EntitySet<MainLogDO> selects = anylineService.selects(getTableName(MainLogDO.class), MainLogDO.class, configStore);
//            anylineService.total

            if (CollUtil.isEmpty(selects)) {
                continue;
            }
            list.addAll(selects.stream().toList());

            //找到足够的条数就返回了
            if (list.size() >= size) {
                break;
            }
        }

        List<MainLogDTO> list1 = list.stream().map(v -> {
            MainLogDTO mainLogDTO = BeanUtil.copyProperties(v, MainLogDTO.class);
            return mainLogDTO;
        }).toList();
        pageResult.addAll(list1);
        pageResult.setTotal(count);
        return pageResult;
    }

    @Override
    public List<LogDetailDTO> getDetailByTid(String tid, Date logTime) {

        //必须带入时间查询
        if (ObjectUtil.isNull(logTime)) {
            return Collections.emptyList();
        }
        AnylineService anylineService = initDb(getJdbcUrl(logTime));
        ConfigStore configStore = new DefaultConfigStore();
        configStore.and("tid", tid);
        //开始查询
        EntitySet<LogDetailDO> selects = null;
        try {
            selects = anylineService.selects(getTableName(LogDetailDO.class), LogDetailDO.class, configStore);
        } catch (Exception e) {

        }

        if (CollUtil.isEmpty(selects)) {
            return Collections.emptyList();
        }


        return selects.stream().map(v -> {
            LogDetailDTO mainLogDTO = BeanUtil.copyProperties(v, LogDetailDTO.class);
            mainLogDTO.setFeature(ZipUtil.unZip(mainLogDTO.getFeature()));
            return mainLogDTO;
        }).toList();
    }


    @Override
    public MainLogDTO getMainByTid(String tid,Date logTime) {
        return null;
    }
}
